/*************************************************************************
 * Filename:    Commands.c
 * Description: Contains the test interface commands.
 * Group 2:     nachOS
 * Authors:     Daniel Fairweather
 * Class:       CSE 325
 * Instructor:  Mr. Duggan
 * Assignment:  Lab #3 Scheduler
 * Assigned:    Feburary 12, 2013
 * Due:         Feburary 26, 2013
 *************************************************************************/
#include "Commands.h"

int i = 0;
char* command_name;
char* args[10];
int argc = 0;



void runCommand(){
    /**
     * Init_Sched [general_purpose | interactive] 
     */
    if(strcmp(command_name, "init_sched") == 0 && argc == 1){
        if(strcmp(args[0], "general_purpose") == 0){
            init(0);
            setResult("Fair-Share scheduler activated. Queues reset.");
        }
        else if(strcmp(args[0], "interactive") == 0){
            init(1);
            setResult("Priority scheduler activated. Queues reset.");
        }
        else{
            setResult("Invalid scheduler name.");
        }
    }


    /**
     * Create_Proc psw page-Â­â€table reg0 reg1 reg2
     * Create_Proc pid gid psw page-Â­â€table reg0 reg1 reg2
     */
    else if(strcmp(command_name, "create_proc") == 0 && (argc == 5 || argc == 6)){
        int i = getUniquePID();
        int regs[3] = {0};
        regs[0] = atoi(args[2]);
        regs[1] = atoi(args[3]);
        regs[2] = atoi(args[4]);

        if(argc == 5){
            if(create(i, (i%3)+1, atoi(args[0]), atoi(args[1]), regs) == NULL){
                setResult("Process could not be created. PID or GID invalid.");
            }
            else{
                setResult("Process created.");
            }
        }
        else if(argc == 6){
            if(create(i, atoi(args[5]), atoi(args[1]), atoi(args[2]), regs) == NULL){
                setResult("Process could not be created. PID or GID invalid.");
            }
            else{
                setResult("Process created.");
            }
        }
    }



    /**
     * LIST queue_name|ALL|SCHED
     */
    else if(strcmp(command_name, "list") == 0 && argc == 1 && getTestMode() != 2){
        if(strcmp(args[0], "all") == 0){
            listQueues();
        }
        else if(strcmp(args[0], "new") == 0){
            listQueue(0);
        }
        else if(strcmp(args[0], "ready") == 0){
            listQueue(1);
        }
        else if(strcmp(args[0], "running") == 0){
            listQueue(2);
        }
        else if(strcmp(args[0], "waiting") == 0){
            listQueue(3);
        }
        else if(strcmp(args[0], "terminated") == 0){
            listQueue(4);
        }
        else if(strcmp(args[0], "sched") == 0){
            if(next_process != NULL){
                printProcess(next_process);
                printf("\n");
            }
            else{
                setResult("The scheduler has not yet determined the next process to be run.");
            }
        }
        else{
            setResult("Invalid queue name.");
        }
    }



    /**
     * GO 
     */
    else if(strcmp(command_name, "go") == 0 && argc == 0){
        if(go() != NULL){
            setResult("Moved process to running queue.");
        }
        else{
            setResult("Could not move process to running queue.");
        }
    }

    

    /**
     * UNWAIT PID
     */
    else if(strcmp(command_name, "unwait") == 0 && argc == 1){
        if(unwait(atoi(args[0])) != NULL){
            setResult("Moved process to ready queue.");
        }
        else{
            setResult("Could not move process to ready queue.");
        }
    }



    /**
     * EOQUANTUM
     */
    else if(strcmp(command_name, "eoquantum") == 0 && argc == 0){
        if(eoQuantum() != NULL){
            setResult("Moved process to ready queue.");
        }
        else{
            setResult("Could not move process to ready queue.");
        }
    }



    /**
     * EOLIFE
     */
    else if(strcmp(command_name, "eolife") == 0 && argc == 0){
        if(eoLife() != NULL){
            setResult("Moved process to terminated queue.");
        }
        else{
            setResult("Could not move process to terminated queue.");
        }
    }



    /**
     * WAIT
     */
    else if(strcmp(command_name, "wait") == 0 && argc == 0){
        if(wait() != NULL){
            setResult("Moved process to waiting queue.");
        }
        else{
            setResult("Could not move process to waiting queue.");
        }
    }



    /**
     * TERMINATE
     */
    else if(strcmp(command_name, "terminate") == 0 && argc == 1){
        if(terminate(atoi(args[0])) != NULL){
            setResult("Terminated process.");
        }
        else{
            setResult("Could not terminate process.");
        }
    }



    /**
     * TESTMODE
     */
    else if(strcmp(command_name, "testmode") == 0 && argc == 1){
        if(strcmp(args[0], "dynamic") == 0){
            setTestMode(2);
            setResult("Changed test mode to dynamic.");
        }
        else if(strcmp(args[0], "static") == 0){
            setTestMode(1);
            setResult("Changed test mode to static.");
        }
        else if(strcmp(args[0], "redirection") == 0){
            setTestMode(0);
            setResult("Changed test mode to redirection.");
        }
        else{
            setResult("Invalid test mode.");
        }
    }



    /**
     * EXIT
     */
    else if((strcmp(command_name, "exit") == 0 || strcmp(command_name, "q") == 0 || strcmp(command_name, "quit") == 0) && argc == 0 ){
        exit(1);
    }



    /**
     * Command doesn't exist or had wrong number of arguments.
     */
    else{
        setResult("Invalid command or number of arguments");
    }
}



void processCommand(char* command){
    command_name = strtok(command, " ");
    argc = 0;

    /* Get all of the arguments. */
    while(command_name != NULL && argc < 10){
        args[argc] = strtok(NULL, " ");
        if(args[argc] == NULL){
            break;
        }
        argc++;
    }

    runCommand(); /* Run the command. */
}



void setResult(char* string){
    if(getTestMode() == 2){
        strcpy(result, string);
    }
    else if(getTestMode() == 0 || getTestMode() == 1){
        printf("    %s\n", string);
    }
}